Skip to content

feat(lightspeed): add Sources chip + popover for notebook context#3672

Open
its-mitesh-kumar wants to merge 5 commits into
redhat-developer:mainfrom
its-mitesh-kumar:feat/lightspeed-notebook-sources-chip-popover
Open

feat(lightspeed): add Sources chip + popover for notebook context#3672
its-mitesh-kumar wants to merge 5 commits into
redhat-developer:mainfrom
its-mitesh-kumar:feat/lightspeed-notebook-sources-chip-popover

Conversation

@its-mitesh-kumar

@its-mitesh-kumar its-mitesh-kumar commented Jul 3, 2026

Copy link
Copy Markdown
Member

Description

Replace the inline SourcesCard in the Notebook view with a compact "N Sources" chip button that opens a PatternFly Popover displaying source documents. Each source is shown with a colored FileTypeIcon badge and optional description summary. This change is scoped exclusively to the Notebook context — the general chat view retains its original inline sources display.

Also consolidates source document handling during streaming to use the shared transformDocumentsToSources utility for consistency, and adds i18n translations for all 5 supported languages (Japanese, French, German, Spanish, Italian).

Fixed

UI after changes

S_.2026-07-03.at.1.02.25.PM.mov
S_.2026-07-03.at.1.03.36.PM.mov
S_.2026-07-03.at.1.04.11.PM.mov
S_.2026-07-03.at.2.11.46.PM.mov

✔️ Checklist

  • A changeset describing the change and affected packages. (more info)
  • Added or Updated documentation
  • Tests for new functionality and regression tests for bug fixes
  • Screenshots attached (for UI changes)

Replace the inline SourcesCard with a compact chip button that opens
a PatternFly Popover showing source documents with FileTypeIcon badges.
Scoped to Notebook view only; general chat retains the original display.
Includes i18n translations for all 5 languages, unit tests, and
consistent source document handling during streaming.

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
@rhdh-gh-app

rhdh-gh-app Bot commented Jul 3, 2026

Copy link
Copy Markdown

Important

This PR includes changes that affect public-facing API. Please ensure you are adding/updating documentation for new features or behavior.

Changed Packages

Package Name Package Path Changeset Bump Current Version
@red-hat-developer-hub/backstage-plugin-lightspeed workspaces/lightspeed/plugins/lightspeed minor v2.9.1

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.10526% with 3 lines in your changes missing coverage. Please review.
✅ Project coverage is 54.17%. Comparing base (c990755) to head (78b6164).
⚠️ Report is 18 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #3672      +/-   ##
==========================================
+ Coverage   54.12%   54.17%   +0.04%     
==========================================
  Files        2344     2346       +2     
  Lines       89539    89631      +92     
  Branches    25026    25063      +37     
==========================================
+ Hits        48460    48554      +94     
+ Misses      39517    39515       -2     
  Partials     1562     1562              
Flag Coverage Δ *Carryforward flag
adoption-insights 83.70% <ø> (ø) Carriedforward from 102d13e
ai-integrations 67.95% <ø> (ø) Carriedforward from 102d13e
app-defaults 69.79% <ø> (ø) Carriedforward from 102d13e
augment 46.39% <ø> (ø) Carriedforward from 102d13e
boost 74.68% <ø> (ø) Carriedforward from 102d13e
bulk-import 72.46% <ø> (ø) Carriedforward from 102d13e
cost-management 14.10% <ø> (ø) Carriedforward from 102d13e
dcm 61.81% <ø> (ø) Carriedforward from 102d13e
extensions 61.53% <ø> (ø) Carriedforward from 102d13e
global-floating-action-button 71.18% <ø> (ø) Carriedforward from 102d13e
global-header 59.71% <ø> (ø) Carriedforward from 102d13e
homepage 49.84% <ø> (ø) Carriedforward from 102d13e
install-dynamic-plugins 56.77% <ø> (ø) Carriedforward from 102d13e
konflux 91.49% <ø> (ø) Carriedforward from 102d13e
lightspeed 69.05% <92.10%> (+0.55%) ⬆️
mcp-integrations 85.46% <ø> (ø) Carriedforward from 102d13e
orchestrator 37.71% <ø> (ø) Carriedforward from 102d13e
quickstart 65.63% <ø> (ø) Carriedforward from 102d13e
sandbox 79.56% <ø> (ø) Carriedforward from 102d13e
scorecard 82.67% <ø> (ø) Carriedforward from 102d13e
theme 61.26% <ø> (ø) Carriedforward from 102d13e
translations 7.25% <ø> (ø) Carriedforward from 102d13e
x2a 78.68% <ø> (ø) Carriedforward from 102d13e

*This pull request uses carry forward flags. Click here to find out more.


Continue to review full report in Codecov by Harness.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update c990755...78b6164. Read the comment docs.

🚀 New features to boost your workflow:
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@its-mitesh-kumar

Copy link
Copy Markdown
Member Author

@HusneShabbir Lets firstly wait for @ShiranHi feedback, then only go for go for testing it. There are differences wrt to prototype like we are using PF popups and tried not overriding it much to look exactly as our prototype. Secondly in RHDH 2.1 we will not have the document summary, so we will be only showing documents name, that's why I added the lines between each doscuments.

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
@its-mitesh-kumar

Copy link
Copy Markdown
Member Author

/fs-review

@fullsend-ai-review

fullsend-ai-review Bot commented Jul 3, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 9:07 AM UTC · Completed 9:21 AM UTC
Commit: 0186e63 · View workflow run →

@fullsend-ai-review

Copy link
Copy Markdown

Review

Findings

Medium

  • [injection-vuln] workspaces/lightspeed/plugins/lightspeed/src/components/SourcesChipModal.tsx:133 — The handleSourceClick function passes the link value directly to window.open() without URL scheme validation. The link originates from backend data (doc_url via transformDocumentsToSources). If backend data were poisoned, a javascript: URI could execute arbitrary code in the user's browser context. The if (link) guard only checks truthiness, not the URL scheme.
    Remediation: Validate the URL protocol before calling window.open():

    const url = new URL(link, window.location.origin);
    if (!['http:', 'https:'].includes(url.protocol)) return;
  • [logic-error] workspaces/lightspeed/plugins/lightspeed/src/components/SourcesChipModal.tsx:139 — When isExternal is falsy, handleSourceClick calls window.open(link, '_self'), which navigates the entire browser window away from the Backstage SPA. This causes the user to lose their chat session and application state. In practice, transformDocumentsToSources sets isExternal: !!doc?.doc_url, so any source with a URL will have isExternal=true — making this branch reachable only if isExternal is explicitly set to false while a link is provided. The likelihood is low, but the logic is semantically incorrect.
    Remediation: Either always open links in a new tab (_blank with noopener,noreferrer) or use client-side navigation for internal links.

Low

  • [test-inadequate] workspaces/lightspeed/plugins/lightspeed/src/components/__tests__/SourcesChipModal.test.tsx — The test suite covers rendering, popover open/close, fallback titles, and source display, but does not verify window.open behavior when a source link is clicked. The handleSourceClick function contains branching logic (external vs non-external) that would benefit from test coverage.

  • [insufficient-referrer-protection] workspaces/lightspeed/plugins/lightspeed/src/components/SourcesChipModal.tsx:139 — When isExternal is true, window.open is called with 'noreferrer' but not 'noopener'. Modern browsers treat noreferrer as implying noopener, but using 'noopener,noreferrer' would be defense-in-depth.

  • [translation-cast-idiom] workspaces/lightspeed/plugins/lightspeed/src/components/SourcesChipModal.tsx:193 — The translation call uses (t as Function)(...). While this pattern exists in ~7 places in the notebooks area, the dominant codebase convention (~16 occurrences) is t('key' as any, { params }). Consider aligning with the more prevalent pattern.

  • [naming-convention] workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBox.tsx:118 — The prop useSourcesChipModal reads like a React hook name (the use prefix is conventionally reserved for hooks). Other boolean props in this component use patterns like topicRestrictionEnabled, isStreaming. Consider renaming to showSourcesChipPopover or sourcesChipPopoverEnabled.

@fullsend-ai-review fullsend-ai-review Bot added the requires-manual-review Review requires human judgment label Jul 3, 2026
@ShiranHi

ShiranHi commented Jul 5, 2026

Copy link
Copy Markdown

Thank you @its-mitesh-kumar, looks good to me. I understand that we are unable to remove the border line between each result or change the 'i' icon from purple to gray. If that’s a constraint, I am completely fine with this implementation. Thank you!

@its-mitesh-kumar

Copy link
Copy Markdown
Member Author

@ShiranHi

we are unable to remove the border line between each result or change

We can remove the border line between each result. I did introduced it knowingly to look better. In 2.1 we will be only having only document name. Let me know your preference.

S_.2026-07-03.at.1.03.36.PM.mov

change the 'i' icon from purple to gray.

We can change the 'i' icon from purple to gray. I made it purple since to me its look better particularly in light theme. Let me know your preference.

@its-mitesh-kumar

its-mitesh-kumar commented Jul 6, 2026

Copy link
Copy Markdown
Member Author

@ShiranHi Made both changes now

Light Theme

S_ 2026-07-06 at 8 04 21 PM

Dark Theme

S_ 2026-07-06 at 8 04 40 PM

Cc: @HusneShabbir

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>

@HusneShabbir HusneShabbir left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Implementation looks good.

Just one question: is there a reason we're using a different close button icon here? Wouldn't it be better to keep it consistent with the close icon used elsewhere?

Image

.

Image

@its-mitesh-kumar

Copy link
Copy Markdown
Member Author

Implementation looks good.

Just one question: is there a reason we're using a different close button icon here? Wouldn't it be better to keep it consistent with the close icon used elsewhere?

Image . Image

@HusneShabbir this close icon is coming from PF popover. So lets not try to override it.

@HusneShabbir

Copy link
Copy Markdown
Member

cc: @ShiranHi

@ciiay

ciiay commented Jul 7, 2026

Copy link
Copy Markdown
Member

@HusneShabbir this close icon is coming from PF popover. So lets not try to override it.

@its-mitesh-kumar do we have a bug ticket for this issue? It affects MCP config modal icons too, the x icon and key icon. We need to find a universal fix for this.

@ciiay ciiay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pr 👏 Mostly looks good to me, only left a couple nit comments. Also it might be worth adding a LightspeedChatBox test with useSourcesChipModal and updating the Message mock to render extraContent.endContent.

Comment thread workspaces/lightspeed/plugins/lightspeed/src/components/SourcesChipModal.tsx Outdated
Comment thread workspaces/lightspeed/plugins/lightspeed/src/components/LightspeedChatBox.tsx Outdated
@its-mitesh-kumar

Copy link
Copy Markdown
Member Author

@HusneShabbir this close icon is coming from PF popover. So lets not try to override it.

@its-mitesh-kumar do we have a bug ticket for this issue? It affects MCP config modal icons too, the x icon and key icon. We need to find a universal fix for this.

@ciiay Since its PF close icon only. So lets use this only. At other places if we are importing close icon from MUI or somewhere else we can change that and use PF close icon throughout lightspeed.

Signed-off-by: its-mitesh-kumar <itsmiteshkumar98@gmail.com>
@sonarqubecloud

sonarqubecloud Bot commented Jul 7, 2026

Copy link
Copy Markdown

@its-mitesh-kumar its-mitesh-kumar requested a review from ciiay July 7, 2026 20:50
@ciiay

ciiay commented Jul 8, 2026

Copy link
Copy Markdown
Member

@ciiay Since its PF close icon only. So lets use this only. At other places if we are importing close icon from MUI or somewhere else we can change that and use PF close icon throughout lightspeed.

Not only the close icon. It happens to key icon on MCP config modal as well. Before the issue gets resolved in upstream, what can we do from our level? Do you think we need a jira ticket to track this issue?

@ciiay ciiay left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the pr 👏

/lgtm

@openshift-ci openshift-ci Bot added the lgtm label Jul 8, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants